package com.je.workflow.service.push;

import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.je.bpm.core.model.BpmnModel;
import com.je.bpm.core.model.FlowElement;
import com.je.bpm.core.model.config.ProcessRemindTypeEnum;
import com.je.bpm.core.model.config.process.MessageSettingConfigImpl;
import com.je.bpm.core.model.task.KaiteBaseUserTask;
import com.je.bpm.engine.earlyWarning.EarlyWarningPush;
import com.je.bpm.engine.impl.persistence.entity.EarlyWarningEntity;
import com.je.bpm.engine.impl.persistence.entity.TaskEntity;
import com.je.bpm.engine.task.GetTakeNodeNameUtil;
import com.je.common.base.DynaBean;
import com.je.common.base.message.vo.NoticeMsg;
import com.je.common.base.message.vo.PushSystemMessage;
import com.je.common.base.service.MetaService;
import com.je.common.base.util.DateUtils;
import com.je.common.base.util.SecurityUserHolder;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.message.rpc.PortalRpcService;
import com.je.message.rpc.SocketPushMessageRpcService;
import com.je.message.vo.WebPushTypeEnum;
import com.je.workflow.service.push.pojo.MessageDTO;
import com.je.workflow.service.user.WorkFlowUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class EarlyWarningPushImpl implements EarlyWarningPush {
    @Autowired
    private WorkFlowUserService workFlowUserService;
    @Autowired
    private PushService pushService;
    @Autowired
    private PortalRpcService portalRpcService;
    @Autowired
    private SocketPushMessageRpcService socketPushMessageRpcService;
    @Autowired
    private MetaService metaService;

    @Override
    public void alertArrivalReminder(BpmnModel bpmnModel, KaiteBaseUserTask kaiteBaseUserTask, EarlyWarningEntity earlyWarningEntity,
                                     TaskEntity taskEntity, Map<String, Object> beanValue, String submitUserId) {
        String title = "预警提醒";
        String content = String.format("流程提醒：由%s在%s给您提交了%s任务，请尽快处理!", workFlowUserService.getUserNameById(submitUserId),
                DateUtils.formatDateTime(taskEntity.getCreateTime()),
                bpmnModel.getMainProcess().getName());
        send(bpmnModel, taskEntity, content, title, submitUserId);
    }

    @Override
    public void warningReminder(BpmnModel bpmnModel, KaiteBaseUserTask kaiteBaseUserTask, EarlyWarningEntity earlyWarningEntity,
                                TaskEntity taskEntity, Map<String, Object> beanValue, String submitUserId) {
        String title = "预警提醒";
        String content = String.format("流程提醒：由%s在%s给您提交了%s任务，请尽快处理!", workFlowUserService.getUserNameById(submitUserId),
                DateUtils.formatDateTime(taskEntity.getCreateTime()),
                bpmnModel.getMainProcess().getName());
        send(bpmnModel, taskEntity, content, title, submitUserId);
    }

    private Map<String, String> buildContext(List<ProcessRemindTypeEnum> list, String submitUserId, TaskEntity taskEntity, BpmnModel bpmnModel) {
        FlowElement flowElement = bpmnModel.getMainProcess().getFlowElement(taskEntity.getTaskDefinitionKey());
        String taskName = flowElement.getName();
        if (Strings.isNullOrEmpty(taskName)) {
            taskName = GetTakeNodeNameUtil.builder().getTakeNodeName(flowElement);
        }
        Map<String, String> map = new HashMap<>();
        String userName = workFlowUserService.getUserNameById(submitUserId);
        String context = "";
        for (ProcessRemindTypeEnum processRemindTypeEnum : list) {
            if (processRemindTypeEnum == ProcessRemindTypeEnum.WEB) {
                context = String.format("流程提醒：由<font color=red>%s</font>在%s给您提交了%s任务,当前活动%s,请尽快审批",
                        userName, DateUtils.formatDateTime(taskEntity.getCreateTime()), bpmnModel.getMainProcess().getName()
                        , taskName);
                map.put(ProcessRemindTypeEnum.WEB.toString(), context);
            } else if (processRemindTypeEnum == ProcessRemindTypeEnum.EMAIL) {
                context = String.format("你有一条任务需要审批!<br>\n" +
                                "由%s在%s给您提交了%s流程任务<br>\n" +
                                "当前活动：%s，请尽快审批!<br>", userName, DateUtils.formatDateTime(taskEntity.getCreateTime()),
                        bpmnModel.getMainProcess().getName(), taskName);
                map.put(ProcessRemindTypeEnum.EMAIL.toString(), context);
            } else if (processRemindTypeEnum == ProcessRemindTypeEnum.NOTE) {
                context = String.format("流程提醒：由%s在%s给您提交了%s任务，请尽快处理!", userName, DateUtils.formatDateTime(taskEntity.getCreateTime()),
                        bpmnModel.getMainProcess().getName());
                map.put(ProcessRemindTypeEnum.NOTE.toString(), context);
            }
        }
        return map;
    }

    private void send(BpmnModel bpmnModel, TaskEntity taskEntity, String content, String title, String submitUserId) {
        Map<String, String> contents = new HashMap<>();
        String associationId = workFlowUserService.getAssociationIdById(taskEntity.getAssignee());
        String jeCloudDingTalkId = bpmnModel.getMainProcess().getMessageSetting().getJeCloudDingTalkId();
        List<DynaBean> list = metaService.select("JE_WORKFLOW_EXIGENCY", ConditionsWrapper.builder()
                .eq("EXIGENCY_PKVALUE", taskEntity.getBusinessKey()));
        String urgency = "";
        if (list.size() > 0) {
            urgency = list.get(0).getStr("EXIGENCY_TYPE");
        }
        MessageDTO messageDTO = MessageDTO.build(title, bpmnModel.getMainProcess().getName(),
                "", taskEntity.getBusinessKey(), bpmnModel.getMainProcess().getProcessConfig().getFuncCode(),
                jeCloudDingTalkId, urgency);
        //左下角通知弹出框
        List<String> pushType = new ArrayList<>();
        MessageSettingConfigImpl messageSettingConfig = bpmnModel.getMainProcess().getMessageSetting();
        for (ProcessRemindTypeEnum processRemindTypeEnum : messageSettingConfig.getMessages()) {
            pushType.add(processRemindTypeEnum.toString());
        }
        contents = buildContext(messageSettingConfig.getMessages(), submitUserId, taskEntity, bpmnModel);
        pushService.pushUrgeMsg(associationId, messageDTO, pushType, content, title, contents);
        JSONObject showFuncFormInfo = new JSONObject();
        if (!Strings.isNullOrEmpty(taskEntity.getBusinessKey())) {
            showFuncFormInfo.put("funcCode", bpmnModel.getMainProcess().getProcessConfig().getFuncCode());
            showFuncFormInfo.put("beanId", taskEntity.getBusinessKey());
        }
        NoticeMsg noticeMsg = new NoticeMsg(associationId, workFlowUserService.getUserNameById(taskEntity.getAssignee()),
                workFlowUserService.getUserDeptIdById(taskEntity.getAssignee()), workFlowUserService.getUserDeptNameById(taskEntity.getAssignee()),
                content, title, "MSG", "消息", showFuncFormInfo.toJSONString());
        //添加通知
        portalRpcService.insertNoticeMsg(noticeMsg);
        //添加通知添加又上方的红点
        portalRpcService.insertOrUpdateSign(associationId,
                workFlowUserService.getUserDeptIdById(taskEntity.getAssignee()), WebPushTypeEnum.MSG, "insert");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", "MSG");
        jsonObject.put("type", "MSG_MSG");
        jsonObject.put("data", "");
        jsonObject.put("notify", "");
        PushSystemMessage pushSystemMessage = new PushSystemMessage("MSG", String.valueOf(jsonObject));
        List<String> targetUserIds = new ArrayList<>();
        targetUserIds.add(associationId);
        pushSystemMessage.setTargetUserIds(targetUserIds);
        pushSystemMessage.setSourceUserId(SecurityUserHolder.getCurrentAccountId());
        //发送通知刷新右上角的红点标识
        socketPushMessageRpcService.sendMessage(pushSystemMessage);
        JSONObject jsonObjectMyShare = new JSONObject();
        jsonObjectMyShare.put("code", "COLLECTION");
        jsonObjectMyShare.put("type", "MSG_MSG");
        jsonObjectMyShare.put("data", "");
        jsonObjectMyShare.put("notify", "");
        PushSystemMessage pushSystemMessageMyShare = new PushSystemMessage("", String.valueOf(jsonObjectMyShare));
        pushSystemMessageMyShare.setTargetUserIds(Lists.newArrayList(SecurityUserHolder.getCurrentAccountRealUserId()));
        pushSystemMessageMyShare.setSourceUserId("系统");
        socketPushMessageRpcService.sendMessage(pushSystemMessageMyShare);
    }


}
